#pragma once

#include<iostream>
#include <sys/types.h>
#include <sys/socket.h>

#include"Connection.hpp"
#include"Log.hpp"

const int buffsize=512;
class HandlerConnection
{
public:
    HandlerConnection(handler_t process):_process(process)
    {}
    void HandlerRecver(Connection* conn)
    {
        errno=0;
        // LOG(DEBUG,"Client message sockfd:%d\n",conn->Sockfd());
        while(true)
        {
            char buff[buffsize];
            ssize_t n=::recv(conn->Sockfd(),buff,sizeof(buff)-1,0);
            if(n>0)
            {
                buff[n]=0;
                LOG(DEBUG,"inbuffer:%s,size:%d\n",buff,n);

                conn->AppendInBuff(buff);
            }
            // else if(n==0)
            // {
            //     LOG(INFO,"[%s:%d] 客户端已经退出\n".conn->_addr.Ip(),conn->_addr.Port());
            //     conn->_handler_excepter(conn);
            // }
            else
            {
                if(errno==EWOULDBLOCK)
                {
                    LOG(DEBUG,"读取完毕\n");
                    break;
                }
                else if(errno==EINTR)
                {
                    continue;
                }
                else
                {
                    conn->_handler_excepter(conn);
                    return;
                }
            }
            
        }
        //底层数据读取完毕，开始处理数据
        std::cout<<conn->InBuffer()<<std::endl;
        _process(conn);//业务处理
        // LOG(DEBUG,"outbuffer:%s\n",conn->OutBuffer().c_str());
    }
    void HandlerSender(Connection* conn)
    {
        errno=0;
        LOG(DEBUG,"inoutbuffer:%s\n",conn->OutBuffer().c_str());

        while(true)
        {
            ssize_t n=::send(conn->Sockfd(),conn->OutBuffer().c_str(),conn->OutBuffer().size(),0);
            if(n>0)
            {
                conn->DiscardOutbuffer(n);
                if(conn->OutBuffer().empty())break;
            }
            else if(n==0)//缓冲区中没有数据了
            {
                break;
            }
            else
            {
                if(errno==EWOULDBLOCK)//发送缓冲区满了,等待epoll事件就绪
                {
                    break;
                }
                else if(errno==EINTR)//信号中断
                {
                    continue;
                }
                else
                {
                    conn->_handler_excepter(conn);
                    return;
                }
            }
        }
        //发送条件不满足需要添加epoll关心事件
        if(!conn->OutBuffer().empty())
        {
            conn->_R->EnableConnectionReadWrite(conn->Sockfd(),true,true);
        }
        else
        {
            conn->_R->EnableConnectionReadWrite(conn->Sockfd(),true,false);
        }
    }
    void HandlerExcepter(Connection* conn)
    {
        //出异常，如：客户端断开链接，读写出问题等逻辑异常，删除链接
        conn->_R->DelConnection(conn->Sockfd());
    }
private:
    handler_t _process;
};